package com.fount4j.generator.introspector.extend;

import com.fount4j.generator.context.GeneratorContext;
import com.fount4j.generator.exception.GenerateException;
import com.fount4j.generator.info.ColumnInfo;
import com.fount4j.generator.info.EntityInfo;
import com.fount4j.generator.introspector.JavaClassIntrospector;
import com.fount4j.generator.util.BeanUtils;
import com.fount4j.generator.util.GeneratorFileUtils;
import com.fount4j.generator.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * 实体类解析器
 *
 * @author Morven 2016/12/22
 */
public class EntityIntrospector extends JavaClassIntrospector {
    /** 忽略表的前缀 */
    protected String ignoreTablePrefix;

    /**
     * 解析实体类信息
     *
     * @param context 生成器上下文
     */
    @Override
    public void introspect(GeneratorContext context) {
        EntityInfo info = new EntityInfo();
        introspectName(context, info);
        introspectPackage(context, info);
        introspectFile(context, info);
        introspectImports(context, info);
        context.putInfo(infoKey, info);
    }

    /**
     * 解析实体类文件路径
     *
     * @param context 生成器上下文
     * @param info    EntityInfo
     */
    protected void introspectFile(GeneratorContext context, EntityInfo info) {
        String packageName = context.getTableConfig().getString("entityPackage");
        if (StringUtils.isBlank(packageName)) {
            packageName = this.packageName;
        }

        File file = GeneratorFileUtils.getFile(this.resourcePath, packageName, info.getName() + ".java");
        info.setFile(file);
        try {
            info.setCustomContent(GeneratorFileUtils.getCustomContent(file));
        } catch (IOException e) {
            throw new GenerateException("读取文件自定义内容出错: " + file, e);
        }
    }

    /**
     * 解析实体类的类名
     *
     * @param context 生成器上下文
     * @param info    EntityInfo
     */
    protected void introspectName(GeneratorContext context, EntityInfo info) {
        String entityName = context.getTableConfig().getString("entityName");
        if (StringUtils.isBlank(entityName)) {
            String tableName = context.getTableInfo().getRealName();
            if (StringUtils.isNotBlank(ignoreTablePrefix)) {
                String[] split = ignoreTablePrefix.split(",");
                for (String pre : split) {
                    String prefix = pre.trim();
                    if (tableName.startsWith(prefix)) {
                        tableName = tableName.replaceFirst(prefix, "");
                        break;
                    }
                }
            }
            entityName = StringUtils.firstUpper(StringUtils.lineToHump(tableName.toUpperCase()));
        }
        info.setName(entityName);
    }

    /**
     * 解析表
     *
     * @param context 生成器上下文
     * @param info    EntityInfo
     */
    protected void introspectPackage(GeneratorContext context, EntityInfo info) {
        String packageContent = context.getTableConfig().getString("entityPackage");
        if (StringUtils.isBlank(packageContent)) {
            packageContent = this.packageName;
        }

        String reference = info.getName();
        if (StringUtils.isBlank(packageContent)) {
            packageContent = "";
        } else {
            reference = packageContent + "." + reference;
            packageContent = "package " + packageContent + ";";
        }

        info.setPackageContent(packageContent);
        info.setReference(reference);
    }

    /**
     * 解析实体类需要导入的类
     *
     * @param context 生成器上下文
     * @param info    EntityInfo
     */
    protected void introspectImports(GeneratorContext context, EntityInfo info) {
        List<ColumnInfo> columns = context.getTableInfo().getColumns();
        Set<String> imports = new LinkedHashSet<>();
        File file = info.getFile();
        try {
            List<String> importList = GeneratorFileUtils.getImports(file);
            imports.addAll(importList);
        } catch (IOException e) {
            throw new GenerateException("读取类 import 内容出错: " + file, e);
        }
        for (ColumnInfo column : columns) {
            Class<?> javaType = column.getJavaType();
            if (byte[].class.equals(javaType)) {
                continue;
            }
            String imp = javaType.getName();
            if (imp.startsWith("java.lang.")) {
                continue;
            }
            imports.add(imp);
        }

        if (this.imports != null) {
            imports.addAll(this.imports);
        }

        try {
            BeanUtils.removeUnuseImport(file, imports);
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<String> importList = new ArrayList<>(imports);
        info.setImports(BeanUtils.createImportsList(importList));
    }

    public String getIgnoreTablePrefix() {
        return ignoreTablePrefix;
    }

    public void setIgnoreTablePrefix(String ignoreTablePrefix) {
        this.ignoreTablePrefix = ignoreTablePrefix;
    }
}
